package lib.XML;

import java.io.FileOutputStream;

import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.events.Attribute;

import java.util.ArrayList;
import java.util.Arrays;

import lib.Base.*;
import lib.Common.Cast;

public class XMLWriter {
	/**
	 * Class to write xml document's
	 */
	public XMLWriter() {

	}

	public void WriteFriendlist(ArrayList<Friend> friendList, String xmlFile)
			throws Exception {
		XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
		XMLEventWriter eventWriter = outputFactory
				.createXMLEventWriter(new FileOutputStream(xmlFile));
		XMLEventFactory eventFactory = XMLEventFactory.newInstance();
		XMLEvent end = eventFactory.createDTD("\n");
		StartDocument startDocument = eventFactory.createStartDocument();
		eventWriter.add(startDocument);
		eventWriter.add(eventFactory.createStartElement("", "", "friendlist"));
		eventWriter.add(end);
		for (Friend friend : friendList) {
			createParmStart(eventWriter, "friend", "id", friend.getUserId());
			createNode(eventWriter, "name", friend.getName());
			eventWriter.add(eventFactory.createEndElement("", "", "friend"));
			eventWriter.add(end);
		}
		eventWriter.add(eventFactory.createEndElement("", "", "friendlist"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createEndDocument());
		eventWriter.close();
	}

	public void WriteConversation(ArrayList<Message> conversation,
			String xmlFile) throws Exception {
		XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
		XMLEventWriter eventWriter = outputFactory
				.createXMLEventWriter(new FileOutputStream(xmlFile));
		XMLEventFactory eventFactory = XMLEventFactory.newInstance();
		XMLEvent end = eventFactory.createDTD("\n");
		StartDocument startDocument = eventFactory.createStartDocument();
		eventWriter.add(startDocument);
		eventWriter
				.add(eventFactory.createStartElement("", "", "conversation"));
		eventWriter.add(end);
		for (Message message : conversation) {
			createParmStart(eventWriter, "message", "time", String
					.valueOf(message.getTimestamp()));
			createNode(eventWriter, "userId", message.getUserId());
			createNode(eventWriter, "text", message.getText());
			eventWriter.add(eventFactory.createEndElement("", "", "message"));
			eventWriter.add(end);
		}
		eventWriter.add(eventFactory.createEndElement("", "", "conversation"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createEndDocument());
		eventWriter.close();
	}

	public void WritePublicGroups(PublicGroups publicGroups, String xmlFile)
			throws Exception {
		XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
		XMLEventWriter eventWriter = outputFactory
				.createXMLEventWriter(new FileOutputStream(xmlFile));
		XMLEventFactory eventFactory = XMLEventFactory.newInstance();
		XMLEvent end = eventFactory.createDTD("\n");
		StartDocument startDocument = eventFactory.createStartDocument();
		eventWriter.add(startDocument);
		createParmStart(eventWriter, "publicGroups", "lastUpdate", String
				.valueOf(publicGroups.getTimestamp()));
		for (PublicGroup PG : publicGroups.getPublicGroups()) {
			createParmStart(eventWriter, "group", "id", String.valueOf(PG
					.getID()));
			createNode(eventWriter, "name", PG.getName());
			createNode(eventWriter, "about", PG.getAbout());
			eventWriter.add(eventFactory.createEndElement("", "", "group"));
			eventWriter.add(end);
		}
		eventWriter.add(eventFactory.createEndElement("", "", "publicGroups"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createEndDocument());
		eventWriter.close();
	}

	public void WriteProfile(Profile profil, String xmlFile) throws Exception {
		XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
		XMLEventWriter eventWriter = outputFactory
				.createXMLEventWriter(new FileOutputStream(xmlFile));
		XMLEventFactory eventFactory = XMLEventFactory.newInstance();
		XMLEvent end = eventFactory.createDTD("\n");
		StartDocument startDocument = eventFactory.createStartDocument();
		eventWriter.add(startDocument);
		eventWriter.add(eventFactory.createStartElement("", "", "profile"));
		eventWriter.add(end);
		createNode(eventWriter, "id", profil.getUserId());
		createNode(eventWriter, "name", profil.getUsername());
		if (profil.getPictureId() != null) {
			createNode(eventWriter, "picture", profil.getPictureId());
		}
		if (profil.getLastChange() != 0) {
			createNode(eventWriter, "lastChange", String.valueOf(profil
					.getLastChange()));
		}
		if (profil.getInfo() != null) {
			Info info = profil.getInfo();
			eventWriter.add(eventFactory.createStartElement("", "", "info"));
			eventWriter.add(end);
			eventWriter
					.add(eventFactory.createStartElement("", "", "personal"));
			eventWriter.add(end);
			if (info.getFirstName() != null) {
				createNode(eventWriter, "firstName", info.getFirstName());
			}
			if (info.getLastName() != null) {
				createNode(eventWriter, "lastName", info.getLastName());
			}
			if (info.getGebDay() != 0 || info.getGebMont() != 0
					|| info.getGebYear() != 0) {
				eventWriter.add(eventFactory.createStartElement("", "",
						"gebDate"));
				eventWriter.add(end);
				if (info.getGebDay() != 0) {
					createNode(eventWriter, "day", String.valueOf(info
							.getGebDay()));
				}
				if (info.getGebMont() != 0) {
					createNode(eventWriter, "month", String.valueOf(info
							.getGebMont()));
				}
				if (info.getGebYear() != 0) {
					createNode(eventWriter, "year", String.valueOf(info
							.getGebYear()));
				}
				eventWriter.add(eventFactory
						.createEndElement("", "", "gebDate"));
				eventWriter.add(end);
			}
			if (info.getAbout() != null) {
				createNode(eventWriter, "about", info.getAbout());
			}
			eventWriter.add(eventFactory.createEndElement("", "", "personal"));
			eventWriter.add(end);
			if (!info.getEducations().isEmpty()
					&& !info.getWorkplaces().isEmpty()) {
				eventWriter.add(eventFactory.createStartElement("", "",
						"career"));
				eventWriter.add(end);
				if (!info.getEducations().isEmpty()) {
					eventWriter.add(eventFactory.createStartElement("", "",
							"educations"));
					eventWriter.add(end);
					for (Education education : info.getEducations()) {
						createParmStart(eventWriter, "education", "id", String
								.valueOf(education.getId()));
						createNode(eventWriter, "name", education.getName());
						createNode(eventWriter, "begin", String
								.valueOf(education.getBegin()));
						createNode(eventWriter, "end", String.valueOf(education
								.getEnd()));
						eventWriter.add(eventFactory.createEndElement("", "",
								"education"));
						eventWriter.add(end);
					}
					eventWriter.add(eventFactory.createEndElement("", "",
							"educations"));
					eventWriter.add(end);
				}
				if (!info.getWorkplaces().isEmpty()) {
					eventWriter.add(eventFactory.createStartElement("", "",
							"workplaces"));
					eventWriter.add(end);
					for (Workplace workplace : info.getWorkplaces()) {
						createParmStart(eventWriter, "workplace", "id", String
								.valueOf(workplace.getId()));
						createNode(eventWriter, "name", workplace.getName());
						createNode(eventWriter, "profession", workplace
								.getProfession());
						createNode(eventWriter, "begin", String
								.valueOf(workplace.getBegin()));
						createNode(eventWriter, "end", String.valueOf(workplace
								.getEnd()));
						eventWriter.add(eventFactory.createEndElement("", "",
								"workplace"));
						eventWriter.add(end);
					}
					eventWriter.add(eventFactory.createEndElement("", "",
							"workplaces"));
					eventWriter.add(end);
				}
				eventWriter
						.add(eventFactory.createEndElement("", "", "career"));
				eventWriter.add(end);
			}
			if (!info.getHobbys().isEmpty()) {
				eventWriter.add(eventFactory.createStartElement("", "",
						"hobbys"));
				eventWriter.add(end);
				for (String hobby : info.getHobbys()) {
					createNode(eventWriter, "hobby", hobby);
				}
				eventWriter
						.add(eventFactory.createEndElement("", "", "hobbys"));
				eventWriter.add(end);
			}
			eventWriter.add(eventFactory.createEndElement("", "", "info"));
			eventWriter.add(end);
		}
		if (!profil.getPosts().isEmpty()) {
			eventWriter.add(eventFactory.createStartElement("", "", "posts"));
			eventWriter.add(end);
			for (Post post : profil.getPosts()) {
				createParmStart(eventWriter, "post", "id", String.valueOf(post
						.getId()));
				createNode(eventWriter, "time", String.valueOf(post.getTime()));
				createNode(eventWriter, "text", post.getText());
				if (post.getPictureId() != null) {
					createNode(eventWriter, "picture", post.getPictureId());
				}
				if (!post.getComments().isEmpty()) {
					eventWriter.add(eventFactory.createStartElement("", "",
							"comments"));
					eventWriter.add(end);
					for (Message message : post.getComments()) {
						createParmStart(eventWriter, "message", "time", String
								.valueOf(message.getTimestamp()));
						createNode(eventWriter, "userId", message.getUserId());
						createNode(eventWriter, "text", message.getText());
						eventWriter.add(eventFactory.createEndElement("", "",
								"message"));
						eventWriter.add(end);
					}
					eventWriter.add(eventFactory.createEndElement("", "",
							"comments"));
					eventWriter.add(end);
				}
				eventWriter.add(eventFactory.createEndElement("", "", "post"));
				eventWriter.add(end);
			}
			eventWriter.add(eventFactory.createEndElement("", "", "posts"));
			eventWriter.add(end);
		}
		if (!profil.getGuestbook().isEmpty()) {
			eventWriter.add(eventFactory
					.createStartElement("", "", "guestbook"));
			eventWriter.add(end);
			for (Message message : profil.getGuestbook()) {
				createParmStart(eventWriter, "message", "time", String
						.valueOf(message.getTimestamp()));
				createNode(eventWriter, "userId", message.getUserId());
				createNode(eventWriter, "text", message.getText());
				eventWriter.add(eventFactory
						.createEndElement("", "", "message"));
				eventWriter.add(end);
			}
			eventWriter.add(eventFactory.createEndElement("", "", "guestbook"));
			eventWriter.add(end);
		}
		eventWriter.add(eventFactory.createEndElement("", "", "profile"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createEndDocument());
		eventWriter.close();
	}

	public void WriteSettings(Settings settings, String xmlFile)
			throws Exception {
		XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
		XMLEventWriter eventWriter = outputFactory
				.createXMLEventWriter(new FileOutputStream(xmlFile));
		XMLEventFactory eventFactory = XMLEventFactory.newInstance();
		XMLEvent end = eventFactory.createDTD("\n");
		StartDocument startDocument = eventFactory.createStartDocument();
		eventWriter.add(startDocument);
		eventWriter.add(eventFactory.createStartElement("", "", "settings"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createStartElement("", "", "profile"));
		eventWriter.add(end);
		createNode(eventWriter, "visible", Cast.IntToString(settings
				.getPVisible()));
		createNode(eventWriter, "guestbook", Cast.IntToString(settings
				.getPGuestbook()));
		createNode(eventWriter, "searchable", Cast.BoolToString(settings
				.getPSearchable()));
		createNode(eventWriter, "silent", Cast.BoolToString(settings
				.getPSilent()));
		createNode(eventWriter, "visibleFriendlist", Cast.IntToString(settings
				.getPFriendlist()));
		eventWriter.add(eventFactory.createEndElement("", "", "profile"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createStartElement("", "", "chat"));
		eventWriter.add(end);
		createNode(eventWriter, "allowed", Cast.IntToString(settings
				.getCAllowed()));
		// System.out.println(Cast.IntToString(settings.getCAllowed()));
		eventWriter.add(eventFactory.createEndElement("", "", "chat"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createStartElement("", "", "users"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createStartElement("", "", "blocklist"));
		eventWriter.add(end);
		for (String user : settings.getUBlockList()) {
			createNode(eventWriter, "user", user);
		}
		eventWriter.add(eventFactory.createEndElement("", "", "blocklist"));
		eventWriter.add(end);
		createNode(eventWriter, "allowFinvite", Cast.BoolToString(settings
				.getUAllowedFInvites()));
		eventWriter.add(eventFactory.createEndElement("", "", "users"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createStartElement("", "", "data"));
		eventWriter.add(end);
		createNode(eventWriter, "personalData", Cast.IntToString(settings
				.getDPersonalData()));
		createNode(eventWriter, "careerData", Cast.IntToString(settings
				.getDCareerData()));
		createNode(eventWriter, "hobbys", Cast.IntToString(settings
				.getDHobbys()));
		eventWriter.add(eventFactory.createEndElement("", "", "data"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createStartElement("", "", "groups"));
		eventWriter.add(end);
		createNode(eventWriter, "allowInvites", Cast.BoolToString(settings
				.getGAllowGInvites()));
		// System.out.println(Cast.BoolToString(settings.getGAllowGInvites()));
		eventWriter.add(eventFactory.createEndElement("", "", "groups"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createStartElement("", "", "liveTicker"));
		eventWriter.add(end);
		createNode(eventWriter, "send", Cast.BoolToString(settings.getLTSend()));
		eventWriter.add(eventFactory.createEndElement("", "", "liveTicker"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createEndElement("", "", "settings"));
		eventWriter.add(end);
		eventWriter.add(eventFactory.createEndDocument());
		eventWriter.close();

	}

	private void createNode(XMLEventWriter eventWriter, String name,
			String value) throws XMLStreamException {
		XMLEventFactory eventFactory = XMLEventFactory.newInstance();
		XMLEvent end = eventFactory.createDTD("\n");
		XMLEvent tab = eventFactory.createDTD("\t");
		StartElement sElement = eventFactory.createStartElement("", "", name);
		eventWriter.add(tab);
		eventWriter.add(sElement);
		Characters characters = eventFactory.createCharacters(value);
		eventWriter.add(characters);
		EndElement eElement = eventFactory.createEndElement("", "", name);
		eventWriter.add(eElement);
		eventWriter.add(end);
	}

	private void createParmStart(XMLEventWriter eventWriter, String name,
			String atrName, String atrValue) throws XMLStreamException {
		XMLEventFactory eventFactory = XMLEventFactory.newInstance();
		XMLEvent end = eventFactory.createDTD("\n");
		Attribute attribute = eventFactory.createAttribute(atrName, atrValue);
		StartElement startElement = eventFactory.createStartElement("", "",
				"Item", Arrays.asList(attribute).iterator(), Arrays.asList()
						.iterator());
		eventWriter.add(startElement);
		eventWriter.add(end);
	}
}
